package com.matrix.draft.juc.day7;

import com.matrix.draft.juc.util.JucUtil;
import lombok.Data;

import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * 测试信号量锁
 */
public class TestSemaphore {
    public static void main(String[] args) {
        parkingLot parkingLot = new parkingLot();
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            new Thread(() -> {
                Car car = new Car("比亚迪秦" + finalI);
                int parkIndex = parkingLot.park(car);
                System.err.println(car.getCarName() + "已经停在了" + parkIndex);
                JucUtil.sleep(5000);
                parkingLot.fetch(parkIndex);
                System.err.println(car.getCarName() + "已从" + parkIndex + "取出");
            }).start();
        }
    }
}

class parkingLot {
    private final int SIZE = 3; // 停车场大小
    private Semaphore lock = new Semaphore(SIZE); // 信号量锁
    private AtomicIntegerArray states = new AtomicIntegerArray(SIZE);
    private Car[] cars = new Car[SIZE]; // 车位信息

    // 停车
    public int park(Car car) {
        try {
            // 先尝试获取锁,没锁就等锁
            lock.acquire();
            // 找空闲位置放车
            for (int i = 0; i < SIZE; i++) {
                if (states.get(i) == 0 && states.compareAndSet(i, 0, 1)) {
                    cars[i] = car;
                    return i; // 返回车位号
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            return -1;
        }
        return -1;
    }

    // 取车
    public Car fetch(int i) {
        try {
            cars[i] = null;
            states.set(i, 0);
            return cars[i];
        } finally {
            lock.release();
        }
    }
}

@Data
class Car {
    private String carName;

    public Car(String carName) {
        setCarName(carName);
    }
}